在一般的 React 資料流狀況下
父組件和子組件間只能透過 props 進行溝通
但是在偶爾
非常非常偶爾
的情況下
我們還是會需要在資料流以外對子組件進行變動
像是觸發動畫、音樂媒體的回放等等
像這種時候
可以透過refs來達成
下面就來看看要怎麼作用這個refs吧 :
refs將 DOM 物件作為參數直接呼叫回調函式
我們可以在渲染出來的 html 標籤直接加上refs的屬性:
render() {
     return (
       <div>
         <input
           type="text"
           ref={(input) => { this.textInput = input; }} 
         />
         <input
           type="button"
           value="Focus the text input"
           onClick={this.focusTextInput}
         />
       </div>
     );
   }
這是官方文件中的範例程式
在 input 標籤中加上一個refs屬性
將參數 input 把 DOM 物件傳遞給組件
故當按鈕被按下的時候
組件可以透過this.textInput找到輸入欄位這個節點
並且對其執行focus()
除了 DOM 物件節點refs也可以對組件作用:
import React from 'react';
import ReactDOM from 'react-dom';
class App extends React.Component {
  componentDidMount() {
      console.log(this.textInput);   
  }
  render() {
    return (
      <InputBlock
        ref={(input) => { this.textInput = input; }} />
    );
  }
}
class InputBlock extends React.Component{
   render(){
      return (
          <div>
            <input type="text" value=""/>
         </div>
      );
   }
}
export default App;
當refs的對象是一個組件的時候
參數會變為傳遞整個安裝好的組件
import React from 'react';
import ReactDOM from 'react-dom';
class App extends React.Component {
   constructor(props) {
      super(props);
      this.focusTextInput = this.focusTextInput.bind(this);
   }
   focusTextInput() {
      this.textInput.focus();
   }
   render() {
      return (
         <div>
         <input
            type="text"
            ref={(input) => { this.textInput = input; }} 
         />
         <input
            type="button"
            value="Focus the text input"
            onClick={this.focusTextInput}
         />
         </div>
      );
   }
}
class AutoFocusTextInput extends React.Component {
  componentDidMount() {
    this.textInput.focusTextInput();
  }
  render() {
    return (
      <App
        ref={(input) => { this.textInput = input; }} />
    );
  }
}
export default AutoFocusTextInput;
在這段程式碼用來模擬 初始狀態為已經 focus 輸入欄位 的狀態
這個 AutoFocusTextInput 組件渲染 App 組件
並且在 AutoFocusTextInput 安裝完成的時候透過refs執行 App 組件內部的focusTextInput()
因為在這裡refs將 App 組件作為參數呼叫函式componentDidMount()
所以才找的到componentDidMount()這個函式並且正常執行
refs在 function 型態的組件中沒辦法使用,因為沒有實例(instances)。refs使用前要先考慮是否可以使用狀態資料直接達成,避免過度使用。refs,父組件可以將函式作為特殊的 props 傳遞進去,但一般不建議這麼做。refs被定義做 inline function,那麼每次更新都會被執行兩次,這是因為 React 重新渲染的時候會先清除舊有的再重新產生新的,可以透過改為為 class 型組件中的綁定函式解決這個問題。
- Eva Vue.js 30天隨身包
- Ben那些年,我們一起錯過的Javascript
- Ray激戰ReactJS 30天
Day21 end
by 瑞Ray =͟͟͞͞( •̀д•́)